﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace MapControlSample
{
    public partial class USMapControl : UserControl
    {
        public List<State> States;
        public Color HeatColor;
        public Color RollOverColor;
        
        public USMapControl()
        {
            InitializeComponent();
        }
        public void Update()
        {
            //Get the upper and lower values for the States
            var result = (from s in States
                          select s.Value).Max();
            double StateHigh = result;

            var lowResult = (from s in States
                          select s.Value).Min();
            double StateLow = lowResult;

            UpdateScale(StateHigh, StateLow);


            /* Update Map*/
            foreach (UIElement uie in Map.Children)
            {
                if (uie.GetType().ToString() == "System.Windows.Shapes.Path")
                {
                    Path state = (Path)uie;
                    var stateResult = from s in States
                                      where s.Name == state.Name.Substring(0,2)
                                      select s;
                    foreach (State thisState in stateResult)
                    {
                        FillInStateColor(state, StateHigh, StateLow, thisState);
                    }
                }
            }
        }
        
        private void UpdateScale(double stateHigh, double stateLow)
        {
            double span = stateHigh - stateLow;

            lblMinScale.Text = stateLow.ToString();
            lblMaxScale.Text = stateHigh.ToString();
            foreach (UIElement scaleSeg in Scale.Children)
            {
                switch (scaleSeg.GetType().ToString())
                {
                    case "System.Windows.Shapes.Path":
                        Path scalePath = (Path)scaleSeg;
                        string scaleNumStr = scalePath.Name.Substring(scalePath.Name.IndexOf("_") + 1);
                        int scaleNum = Convert.ToInt32(scaleNumStr);
                        double bottomRange = stateLow + (span * ((scaleNum - 1) * 0.1));
                        double topRange = stateLow + (span * (scaleNum * 0.1));
                        byte opacity = Convert.ToByte(scaleNum * 25);
                        HeatColor.A = opacity;
                        scalePath.Fill = new SolidColorBrush(HeatColor);
                        scalePath.Tag = bottomRange.ToString() + " - " + topRange.ToString();

                        break;
                    case "System.Windows.Shapes.Rectangle":
                        Rectangle scaleRectPath = (Rectangle)scaleSeg;
                        string scaleRectNumStr = scaleRectPath.Name.Substring(scaleRectPath.Name.IndexOf("_") + 1);
                        int scaleRectNum = Convert.ToInt32(scaleRectNumStr);
                        double bottomRectRange = stateLow + (span * ((scaleRectNum - 1) * 0.1));
                        double topRectRange = stateLow + (span * (scaleRectNum * 0.1));
                        byte opacityRect = Convert.ToByte(scaleRectNum * 25);
                        HeatColor.A = opacityRect;
                        scaleRectPath.Fill = new SolidColorBrush(HeatColor);
                        scaleRectPath.Tag = bottomRectRange.ToString() + " - " + topRectRange.ToString();

                        break;

                }
            }
        }


        #region HELPER METHODS
        private void FillInStateColor(Path state, double StateHigh, double StateLow, State thisState)
        {
            state.Tag = thisState;
            int score = GetRangeScore(StateHigh, StateLow, thisState.Value);

            if (HeatColor == null)
            {
                HeatColor = new Color();
                HeatColor.R = 255;
            }


            byte opacity = Convert.ToByte(score * 25);
            HeatColor.A = opacity;
            state.Fill = new SolidColorBrush(HeatColor);
        }
        private int GetRangeScore(double high, double low, double testValue)
        {
            double increment = (high - low) / 10;
            int rtnValue = 0;
            for (int i = 0; i < 10; i++)
            {
                if ((low + (increment * i) <= testValue) && ( testValue <= (low + (increment * (i + 1)))))
                {
                    rtnValue = i+1;
                    i = 10;
                
                }
            }

            return rtnValue;
        }
        #endregion

        #region EVENTS
        private void ScaleSeg_MouseEnter(object sender, MouseEventArgs e)
        {
            switch (sender.GetType().ToString())
            {
                case "System.Windows.Shapes.Path":
                    Path scalePath = (Path)sender;
                    lblHoverSpan.Text = scalePath.Tag.ToString();
                    break;
                case "System.Windows.Shapes.Rectangle":
                    Rectangle scaleRectPath = (Rectangle)sender;
                    lblHoverSpan.Text = scaleRectPath.Tag.ToString();
                    break;
            }
        }
        private void ScaleSeg_MouseLeave(object sender, MouseEventArgs e)
        {
            lblHoverSpan.Text = "";
        }
        private void State_MouseEnter(object sender, MouseEventArgs e)
        {
            Path pathState = (Path)sender;
            State theState = (State)pathState.Tag;
            
            pathState.Fill = new SolidColorBrush(RollOverColor);

            txtStatePopup.Opacity = 1;
            txtStatePopup.Background = new SolidColorBrush(RollOverColor);
            txtStatePopup.Text = theState.Name + ": " + theState.Value.ToString();
            
            Point point = e.GetPosition(null);
            Canvas.SetLeft(txtStatePopup, point.X - 100);
            Canvas.SetTop(txtStatePopup, point.Y);
        }
        private void State_MouseLeave(object sender, MouseEventArgs e)
        {
            Path pathState = (Path)sender;
            State theState = (State)pathState.Tag;
            FillInStateColor(pathState, Convert.ToDouble(lblMaxScale.Text), Convert.ToDouble(lblMinScale.Text), theState);
            txtStatePopup.Text = "";
            txtStatePopup.Opacity = 0;
        }
        #endregion
    }



    public class State
    {
        private string _Name;
        private double _Value;
        private string _Color;

        public string Name
        {
            set
            {
                _Name = value;
            }
            get
            {
                return _Name;
            }
        }
        public double Value
        {
            set
            {
                _Value = value;
            }
            get
            {
                return _Value;
            }
        }
        public string Color
        {
            set
            {
                _Color = value;
            }
            get
            {
                return _Color;
            }
        }  

        public State()
        {
        }
        public State(string name, double value)
        {
            _Name = name;
            _Value = value;
        }
        public State(string name, double inValue, string color)
        {
            _Name = name;
            _Value = inValue;
            _Color = color;
        }


    }
}
